/*
 * commands.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   commands.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   21 sep 2011
 * @brief  Implementation of g-code commands
 */

#ifndef COMMANDS_H
#define COMMANDS_H

#include <stdio.h>
#include <stdbool.h>

/**
 * Enumeration representing the status of response to a command.
 */
enum cmd_status {
  OK,       /**< The command was executed successfully. */
  INVALID,  /**< The request was invalid. */
  FAULT     /**< A hardware fault took place while trying to execute the command. */
};

/**
 * Data structure representing a response to a command.
 */
typedef struct {
  enum cmd_status status; /**< Status of the response. */
  float T;                /**< Temperature of the nozzle in degrees Celsius. */
  float B;                /**< Temperature of the printbed in degrees Celsius. */
  float X;                /**< X coordinate */
  float Y;                /**< Y coordinate */
  float Z;                /**< Z coordinate */
  float E;                /**< E coordinate */
  char *info;             /**< String giving additional information */
} cmd_response_t;


/**
 * Initializes the command component.
 */
void cmd_init(void);

/**
 * G1: Controlled move (buffered)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param x determines the x coordinate of the destination position
 * @param y determines the y coordinate of the destination position
 * @param z determines the z coordinate of the destination position
 * @param e determines the e coordinate of the destination position
 * @param f the maximum speed of the movement in mm/min
 * 
 * Go in a straight line from the current position to the specified position, 
 * with a maximum feed rate of \a f. The x, y, z and e values are interpreted
 * as absolute or relative coordinates, depending on whether G90 or G91 was
 * executed.
 */
void cmd_controlled_move(cmd_response_t *r, float x, float y, float z, float e, float f);

/**
 * G20: Set Units to Inches
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 *
 * This command is not supported and will send an 'invalid' response when 
 * executed.
 */
void cmd_set_units_inches(cmd_response_t *r);

/**
 * G21: Set Units to Millimeters
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * 
 * Units from now on are in millimeters.
 */
void cmd_set_units_millimeters(cmd_response_t *r);

/**
 * G28: Move to Origin (buffered)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param x whether to move the x axis to its origin
 * @param y whether to move the y axis to its origin
 * @param z whether to move the z axis to its origin
 *
 * This causes the machine to move one or more of its axes to its origin.
 */
void cmd_move_to_origin(cmd_response_t *r, bool x, bool y, bool z);

/**
 * @brief G90: Set to absolute positioning (unbuffered)
 * @param r pointer to a cmd_response_t structure to write the response in
 */
void cmd_set_absolute_positioning(cmd_response_t *r);

/**
 * G91: Set to relative positioning (unbuffered)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 */
void cmd_set_relative_positioning(cmd_response_t *r);

/**
 * G92: Set Position
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param x determines the x coordinate of the position
 * @param y determines the y coordinate of the position
 * @param z determines the z coordinate of the position
 * @param e determines the e coordinate of the position
 *
 * Sets the current virtual position to the specified position. The x, y, z and
 * e values are interpreted as absolute or relative coordinates, depending on
 * whether G90 or G91 was executed. 
 */
void cmd_set_position(cmd_response_t *r, float x, float y, float z, float e);

/**
 * M84: Stop idle hold (unbuffered)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 *
 * Stops the idle hold on all axes (including the extruder) by disabling their
 * stepper motors.
 */
void cmd_stop_idle_hold(cmd_response_t *r);

/**
 * M104: Set nozzle temperature (non-blocking)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param c temperature in degrees celcius to which to set the nozzle
 * @see cmd_set_extruder_temp_sync
 * @see cmd_wait
 *
 * Sets the temperature of the nozzle to the specified number of degrees and
 * returns control to the host immediately (i.e. before that temperature has
 * been reached by the extruder).
 */
void cmd_set_extruder_temp_async(cmd_response_t *r, float c);

/**
 * M105: Read extruder and printbed temperature
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 *
 * Reads the current temperature of the nozzle and the print bed in degrees
 * celsius and sends them to the host.
 */
void cmd_read_nozzle_and_printbed_temp(cmd_response_t *r);

/**
 * M109: Set nozzle temperature (blocking)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param c temperature in degrees celcius to which to set the nozzle
 * @see cmd_set_extruder_temp_async
 * @see cmd_wait
 *
 * Sets the temperature of the nozzle to the specified number of degrees and 
 * waits for it to reach that temperature before sending a response back to
 * the host.
 */
void cmd_set_extruder_temp_sync(cmd_response_t *r, float c);

/**
 * M113: Set extruder PWM
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param s pwm value to which to set the extruder motor
 * 
 * This command is not supported because yarf only supports stepper motors,
 * which do not require a PWM to be set. An 'invalid' response will be sent
 * back to the host if the \a s value is anything but NAN.
 */
void cmd_set_extruder_pwm(cmd_response_t *r, float s);

/**
 * M114: Get current position
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 *
 * Sends the current virtual x, y, z and e coordinates to the host.
 */
void cmd_get_position(cmd_response_t *r);

/**
 * M116: Wait
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 *
 * Waits for the nozzle and print bed temperatures to reach their set values.
 */
void cmd_wait(cmd_response_t *r);

/**
 * M140: Set print bed temperature (non-blocking)
 *
 * @param r pointer to a cmd_response_t structure to write the response in
 * @param c temperature in degrees celcius to which to set the print bed
 * @see cmd_wait
 *
 * Sets the temperature of the print bed to the specified number of degrees and
 * returns control to the host immediately (i.e. before that temperature has
 * been reached by the extruder).
 */
void cmd_set_printbed_temp_async(cmd_response_t *r, float c);

/**
 * T: Select tool
 *
 * @param r    pointer to a cmd_response_t structure to write the response in
 * @param tool 0-based index of the tool to select
 *
 * Selects the extruder to build with. Yarf only supports a single extruder, so 
 * this command will send an 'invalid' response when called with any tool index
 * other than 0.
 */
void cmd_select_tool(cmd_response_t *r, int tool);



#endif //COMMANDS_H
